﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Diagnostics;
using MoneyWentWhere.DataModel.Binding;

namespace MoneyWentWhere.DataModel
{
    [TypeConverter(typeof(AccountTypeConverter))]
    [DataContract]
    public class Account : INotifyPropertyChanged, IExtensibleDataObject
    {
        #region Stored properties

        [DataMember(Name = "Guid")]
        Guid _guid;

        [DataMember(Name="Name")]
        string _name;

        [DataMember(Name = "Currency")]
        Currency _currency;

        [DataMember(Name = "Comment")]
        public String Comment;

        [DataMember(Name = "Transactions")]
        public TransactionList Transactions;

        #endregion

        // For serialization
        public Account() 
        {
            _guid = Guid.NewGuid();
        }

        internal Account(MoneyDataSet dataSet, String name, Guid? guid = null)
        {
            if (dataSet == null) { throw new ArgumentNullException("dataSet"); }

            DataSet = dataSet;

            if (guid == null || guid == Guid.Empty) { guid = Guid.NewGuid(); }
            _guid = guid.Value;
            DataSet.StoreObject(_guid, this);

            Transactions = new TransactionList(this);
            Currency = dataSet.DefaultCurrency;
            Name = name;
        }

        public Transaction CreateTransaction(
            decimal amount,
            TransactionKind kind = TransactionKind.Normal,
            DateTime? date = null,
            int suggestedIndex = -1)
        {
            if (!date.HasValue) { date = DateTime.MaxValue; }

            Transaction t = new Transaction(Guid.Empty, this, date.Value, amount,  null, null);

            if (suggestedIndex < 0) { Transactions.Add(t); }
            else { Transactions.Insert(suggestedIndex, t); }
            
            return t;
        }

        public Guid Guid { get { return _guid; } }

        public string Name 
        {
            get { return _name; }
            set
            {
                if (value == _name) { return; }
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        public Currency Currency
        {
            get { return _currency; }
            set
            {
                if (value == _currency) { return; }

                _currency = value;
                if (DataSet != null) { DataSet.Currencies.Add(value); }
                OnPropertyChanged("Currency");                
            }
        }

        public void Delete()
        {
            // NOTE: if adding extra logic, consider putting it in 
            // AccountList.RemoveItem if appropriate.
            DataSet.Accounts.Remove(this);
        }

        public override string ToString()
        {
            return Name + " (" + Currency.Id + ")";
        }

        #region Common Serialization / Notification methods
        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(String name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        [Browsable(false)]
        public ExtensionDataObject ExtensionData { get; set; }

        [Browsable(false)]
        public MoneyDataSet DataSet { get; internal set; }
        #endregion
    }
}
